/**
 * 外呼组件公共状态管理
 * 外呼相关文档
 * @see https://wiki.cticloud.cn/toolbarIndex.html?page=/html/wiki/%E5%B7%A5%E5%85%B7%E6%9D%A1/%E4%BA%8B%E4%BB%B6.html
 * 使用方法: agentAutoCall 为自动拨打电话 参数见callQuery 暂时只需要传 tel 即可实现自动登录、拨打电话
 */
import {Message} from "element-ui"
import {getConfigKey} from "@/api/system/config"
import {checkSpecialWorkOrder} from "@/api/call/call"
import {getShowPhoneNo,clearShowPhoneIndex} from "@/api/call/outphoneno"
import {getTelephoneByUserId} from "@/api/call/telephone"

function callIframe(){
  return document.getElementById('toolbar') ? document.getElementById('toolbar').contentWindow : null
}

const state = {
    isAutoLoginCall : true,     // 是否启用用户登录成功后进行自动登录外呼条
    callBarStatus   : false,    // 呼叫条打开状态 false：关闭 true：打开
    callUser        : null,     // 拨打的对象,
    callState       : null,     // 监听呼叫返回的状态数据,
    loginStatus     : 0,        // 外呼条的登录状态0:未登录 1:已登录
    firstLogin      : false,
    cacheUserCall   : null,
    autoCallTimer   : null,
    ringingResult   : null,     //响铃的数据
    mainUniqueId    : "",       //缓存外呼记录ID
    loginQuery      : null,
    /*{         //外呼登录信息 cno/bindTel 为getInfo user里的agentId
      "validateType"    : "2",
      "enterpriseId"    : "7002407",
      "cno"             : "", //'1117'
      "token"           : "975532d7e91d3955fd5514c3dab6e629",
      "bindTel"         : "",
      "bindType"        : "3",
      "loginStatus"     : "1",
      "pauseDescription": ""
    },*/
    callQuery           : {
      "callType"          : "3",
      "cdrIsAsr"          : "1",
      "obClidAreaCode"    : "",
      "dialTelTimeout"    : "60", //呼叫客户侧超时时间
      "obClid"            : "", //客户侧外显号码
      "tel"               : ""
    }
}

const actions = {
    toggleOpen({commit, dispatch}, params){
        commit('setCallBarStatus', params)
    },
    async callStateResult({commit, state, dispatch}, params){
      console.log('----------外呼回调状态START----------',JSON.stringify(params, null, 2),'----------外呼回调状态END----------')
      await commit("setCallResult", params);

      // 外呼客户已经接通
      if(params.callType == 4 && params.stateAction == "busyOb"){
        dispatch("clearPhotoNo", {})
      }

      if(!state.firstLogin && params.loginStatus === 1 ){
        let {cacheUserCall} = state
        //判断是否有缓存记录，如果有执行拨打操作
        if(cacheUserCall){
          //延时执行，有时提示请求太频繁
          state.autoCallTimer = setTimeout(() => {
            console.log('开始执行自动拨打缓存')
            dispatch('agentAutoCall', cacheUserCall)
          },500)
        }
        //commit("setFirstLogin", {status:true})
      }

    },

    // 清除号码
    clearPhotoNo({state}, payload){
      let tel = state.callQuery.tel || "";
      tel && clearShowPhoneIndex({mobile: tel}).catch(err=>{
        console.log(err.msg || "未知错误")
      })
    },

    // 检测用户是否有特殊工单禁用外拨
    async isBanCall({rootState}, payload){
      console.log('外呼自动拨打 check ban payload=',payload)
      //公司id
      let mchId = rootState.user.userInfo.mchId;
      let mobile = payload.mobile;
      let crmId = payload.crmId;
      const  {msg} = await checkSpecialWorkOrder({
        mobile,
        crmId,
        mchId
      }).catch(err=>{
        Message({
          message: err.msg || "检测工单错误！",
          type: 'error'
        });
        return false
      });
      //return msg === "ban" ? true : false
      return msg
    },

    // 启用工具栏后设置外呼工具条的用户信息
    initCallBarAccount({rootState,state,dispatch}, payload){
      let agentId = rootState.user.agentId; //坐席号
      let params = Object.assign({ ...state.loginQuery },{
        "cno"             : agentId,
        "bindTel"         : agentId,
      }, payload);
      dispatch("setIframeInput", params)
    },

    // 设置iframe表单
    setIframeInput(_, payload){
      let iframe = callIframe()
      if(!iframe) return
      //iframe.document.getElementById("loginType").options[1].selected = true;
      iframe.document.getElementById("loginType").value       = payload.validateType;
      iframe.document.getElementById("loginType").dispatchEvent(new Event("change"));//触发change
      iframe.document.getElementById("enterpriseId").value    = payload.enterpriseId || "";
      iframe.document.getElementById("cno").value             = payload.cno || "";
      iframe.document.getElementById("token").value           = payload.token || "";
      iframe.document.getElementById("bindTel").value         = payload.bindTel || "";
      iframe.document.getElementById("bindType").value        = payload.bindType || "";
      //iframe.document.getElementById("initStatus").value              = payload.initStatus || "";
      //iframe.document.getElementById("cdrIsAsr").value                = payload.cdrIsAsr || "";
    },

    handleLogin(_, payload){
      if(payload.code === "-1"){
        Message({
          message: "软电话注册失败, 请检查麦克风设备后重新登录",
          type: 'error'
        })
      }
    },
    handleKickout(_, payload){
      Message({
        message: "外呼被踢下线，请重新登录",
        type: 'error'
      });
      //console.log(payload.msg);
    },
    async getCallLoginConfig({rootState, commit, dispatch}, payload){
      //查询外呼登录配置文件
      return await getConfigKey("sys.tr.call.login").then(response => {
        if(response.msg != '' && response.msg != undefined){
          // 获取登录配置设置到表单上
          // 获取电话类型 start
          // 查询登录类型配置，默认为3-软电话
          getTelephoneByUserId(rootState.user.userInfo.userId).then(resp => {
            if (resp.data != undefined && resp.data.telephoneType == 2) {
              // 将电话类型改为2-分机号
              response.msg.bindType = "2"
            }
          })
          // 获取电话类型 end
          commit("setCallLoginConfig", JSON.parse(response.msg) || null);
        }
      }).catch(err => {
        Message({
          message: "获取外呼登录配置文件错误，请刷新重试！",
          type: 'error'
        });
      });
    },
    //外呼自动登录
    async agentAutoLogin({rootState, state, dispatch}, payload){
      let iframe = callIframe();
      // 获取iframe登录状态 isOnline
      let isOnline = iframe.isOnline || false
      let agentId = rootState.user.agentId; //坐席号
      if(!state.loginQuery){
        await dispatch("getCallLoginConfig",{});
      }
      if(isOnline){
        Message({
          message: '您已经登录，无需在登录！',
          type: 'warning'
        });
        return
      }
      //校验agentId值后在自动登录
      if(agentId){
        let params = Object.assign({ ...state.loginQuery },{
          "cno"             : agentId,
          "bindTel"         : agentId,
        }, payload);
        console.log('-------开始自动登录----------', JSON.stringify(params, null, 2))
        //调用外呼iframe进行登录
        iframe && iframe.loginToolBar(params);
        //设置iframe 表单值
        await dispatch("setIframeInput", params)
        //Message(agentId)
      } else {
        let errStr = `agentId为必传值, 当前值为${agentId}！`
        console.log(errStr)
        /*Message({
          message: errStr,
          type: 'error'
        })
        throw new Error(errStr);*/
      }

    },
    //外呼自动拨打
    async agentAutoCall({dispatch,state, commit}, payload){
      console.log('外呼自动拨打 payload=',payload)
      let iframe = callIframe();
      let {tel} = payload;
      // 获取iframe登录状态 isOnline
      let isOnline = iframe.isOnline || false; //在线状态
      let isSessionAlive = iframe.CTILink.Session.isSessionAlive(); //通话状态
      const isPhoneNumber = /^[1]([3-9])[0-9]{9}$/.test(payload.tel);
      state.callBarStatus = true;

      //校验手机号码
      if(!payload.tel || !isPhoneNumber) {
        Message({
          message: "请检查电话号码是否正确！",
          type: 'error'
        });
        throw new Error("tel为必传值！");
      }

      //占线提示
      if(isOnline && isSessionAlive){
        Message({
          message: "外呼占线中，请稍后在试！",
          type: 'warning'
        })
        return
      }

      // 检测是否有禁拨工单
      /*const isBan = await dispatch("isBanCall",{
        mobile: tel,
        crmId: payload.crmIdx
      });
      if(isBan === "ban1" ){
        Message({
          message: "该客户禁止外拨，请查看客户工单是否有特殊工单！",
          type: 'warning'
        })
        return false
      }
      else if (isBan === "ban2") {
        Message({
          message: "该客户禁止外拨，请检查呼出黑名单！",
          type: 'warning'
        })
        return false
      }*/

      state.callQuery.tel = payload.tel;
      let params = Object.assign({...state.callQuery}, payload);
      // 获取外显号码
      if(payload.obClid){
        console.log('获取外显号码payload.obClid=',payload.obClid)
        params.obClid = payload.obClid;
      }else{
        try {
          await getShowPhoneNo({mobile: payload.tel}).then( (response) => {
            if(response.data && response.data.showPhoneNo){
              state.callQuery.obClid = response.data.showPhoneNo;
              params.obClid = response.data.showPhoneNo;
            }
          })
        } catch (err){}
      }


      if(!isOnline){
        // 缓存下数据
        await commit("setCacheUserCall", params);
        //外呼未登录去登录
        await dispatch('agentAutoLogin', {}); //call: true, callParams: params
        return
      }

      //开始拨打
      if(isOnline){
        console.log('开始自动拨打！',JSON.stringify(params, null, 2))
        //调用外呼iframe进行拨打
        iframe && iframe.CTILink.Agent.previewOutcall(params)

        //有缓存拨打后置空
        state.cacheUserCall && await commit("setCacheUserCall", null)
      }

    },
}

const getters = {
  // 外呼工具条在线状态
  isOnline(){
    return callIframe() && (callIframe().isOnline || false); //在线状态
  },
  // 外呼工具条是否通话状态
  isSessionAlive(){
    return callIframe() && callIframe().CTILink.Session.isSessionAlive(); //通话状态
  },
  isOpen(state){
      return state.callBarStatus
  },
  // 呼叫状态说明
  getCdrStatusText(state){
    let strMap = {
       1: "座席接听",
       2: "已呼叫座席,座席未接听",
       3: "系统接听",
       4: "系统未接-IVR配置错误",
       5: "系统未接-停机",
      30: "座席未接听",
      31: "座席接听未呼叫客户",
      32: "座席接听,客户未接听",
      33: "双方接听"
    }
    return function(status){
      return strMap[status] || "未知"
    }
  },
  // 呼叫类型
  getCallTypeText(){
    let strMap = {
      1: "呼入",
      4: "预览外呼",
      6: "主叫外呼",
      9: "内部呼叫"
    }
    return function(type){
      return strMap[type] || "未知"
    }
  },
  // 电话类型
  getTelTypeText(){
    let strMap = {
      1: "固话",
      2: "手机"
    }
    return function(type){
      return strMap[type] || "未知"
    }
  },
  // 挂机原因
  getCdrEndReasonText(){
    let strMap = {
      1000: "主通道挂机",
      1001: "非主通道挂机",
      1002: "被强拆"
    }
    return function(type){
      return strMap[type] || "未知"
    }
  },
  // 坐席绑定电话类型
  getCdrAgentNumberTypeText(){
    let strMap = {
      1: "电话",
      2: "分机",
      3: "软电话"
    }
    return function(type){
      return strMap[type] || "未知"
    }
  },
  // 号码状态识别结果
  getCdrDetailSipCauseText(){
    let strMap = {
      710: "忙",
      711: "超时",
      712: "拒接",
      713: "空号",
      714: "关机",
      715: "暂时无法接听",
      716: "停机"
    }
    return function(type){
      return strMap[type] || "未知"
    }
  }
}

const mutations = {
  setCallLoginConfig(state, payload){
    state.loginQuery = payload;
  },
  clearRingingResult(state){
    state.ringingResult = null;
  },
  setCacheUserCall(state, payload){
    state.cacheUserCall     = payload;
  },
  setFirstLogin(state, {status}){
    state.firstLogin      = status || false;
  },
  setCallBarStatus(state, {open}){
    state.callBarStatus   = open || false;
  },
  setCallResult(state, result){
    //响铃数据单存一个，用于业务数据使用
    if(result.state === "响铃"){
      // 呼入
      if(result.callType === 1){
        result.isBack = true
      }
      // 呼出
      if(result.callType === 4){
        result.isCall = true
      }
      state.ringingResult = result;
    }
    state.callState       = result || {};
    state.loginStatus     = result.loginStatus || 0;
  }
}

export default {
    namespaced: true,
    state,
    mutations,
    actions,
    getters
}
